(() => {
    let time = new Date().getTime();
    let cache = sessionStorage.getItem('cache_time');
    if (!cache || time - parseInt(cache) > 1000 * 60 * 60) {
        'all_cats_info tableValue tableKey realThread'.split(' ').forEach(i => sessionStorage.removeItem('cache_' + i));
        sessionStorage.setItem('cache_time', time);
    }
})();
//错误处理
function errorHandle(title, error) {
    console.error("发生错误: " + title);
    console.error(`${title}: ${JSON.stringify(error)}`);
    alert(`发生了一些错误:${title},\n请按F12打开控制台Console查看`);
}
toUUID = buffer => {
    let data = buffer.data;
    let uuid = '';
    for (let x in data)(typeof(x = data[x]) === 'number' && (uuid += ('00' + x.toString(16)).slice(-2)));
    return uuid.toUpperCase();
}
const nameOfData = (() => {
    let data = sessionStorage.getItem('cache_tableValue');
    if (typeof data === 'string') return JSON.parse(data);
    $.ajax({ url: "/basic/table_value", async: false, success: (r) => data = r, });
    sessionStorage.setItem('cache_tableValue', JSON.stringify(data));
    return data;
})();
const indexOfData = (() => {
    let data = {};
    let KVtoVK = kv => {
        let vk = {};
        $.each(kv, (k, v) => vk[v] = k);
        return vk;
    }
    $.each(nameOfData, (table, datas) => {
        data[table] = {};
        $.each(datas, (type, kv) => {
            data[table][type] = KVtoVK(kv);
        });
    });
    return data;
})();

const tableKey = (() => {
    let data = sessionStorage.getItem('cache_tableKey');
    if (typeof data === 'string') return JSON.parse(data);
    $.ajax({ url: "/basic/table_key", async: false, success: (r) => data = r, });
    sessionStorage.setItem('cache_tableKey', JSON.stringify(data));
    return data;
})();
const realThread = (() => {
    let data = sessionStorage.getItem('cache_realThread');
    if (typeof data === 'string') return JSON.parse(data);
    $.ajax({ url: "/basic/real-thread", async: false, success: (r) => data = r, });
    sessionStorage.setItem('cache_realThread', JSON.stringify(data));
    return data;
})();

const all_cats_info = (() => { //获取猫咪信息
    let info = sessionStorage.getItem('cache_all_cats_info');
    if (typeof info === 'string') return JSON.parse(info);
    else info = {};

    let responseJSON = ($.ajax({ url: `/cats/get/all`, async: false })).responseJSON;
    if (!responseJSON.success) return errorHandle('allCatResultError', responseJSON.error);
    else responseJSON = responseJSON.result;
    for (let v in responseJSON) v = responseJSON[v], v.a && (info[v.a] = v, v.aa && (v.aa = toUUID(v.aa)));
    sessionStorage.setItem('cache_all_cats_info', JSON.stringify(info));
    return info;
})();


/**
 * 获取键类型
 * @param k 键
 * @param [value] 进行比对的值
 * @return 当value不存在时, 返回类名. 反之返回比对情况
 * */
function getTableKeyClass(k) {
    let c = (tableKey[k] || {}).c;
    if (arguments.length <= 1 || !c) return c;
    for (let i = 1; i < arguments.length; i++)
        if (arguments[i] == c) return true;
    return false;
}

/**
 *    获取真实数据(被翻译的结果)
 *    @param key 原始键
 *    @param value 原始数据
 *    @return {name: 键名, nameValue: 键数据名, data: 真实数据}
 */
function getRealData(key, value) {
    let info, data;
    info = tableKey[key];
    if (!info) return { name: '', nameValue: '', data: data };
    ((data = nameOfData[info.t]) && (data = data[info.v]) && (data = data[value])) || (data = value);
    if (data === value) {
        if ((data || {}).type === 'Buffer') data = toUUID(data);
    }
    return { name: info.n, nameValue: info.v, data: data };
}

/**
 * 转换为真实名字
 * @param datas string: 尝试转换为真实名字
 * @param datas obj: 尝试将其内部所有键转换为真实名字
 * */
function toRealName(datas) {
    if (typeof datas === 'string') return (tableKey[datas] || {}).v || datas;
    if (!datas) return datas;
    for (let k in datas) {
        let newK = (tableKey[k] || {}).v;
        if (newK) datas[newK] = datas[k];
    }
    return datas;
}

/**
 * 获取 数据库某一项 值->名 的映射
 * 例如 getTableNameValues('basic_info','sex')
 * 返回 Object { 0: "母", 1: "公", "-1": "未知" }
 * 
 * @param table 表名称
 * @param type  字段名
 * @param clone 浅克隆
 * @return 值到名称映射
 * 
 */
function getTableNameValues(table, type, clone) {
    let data = (nameOfData[table] || {})[type];
    if (clone) {
        let newData = {};
        for (let k in data) newData[k] = data[k];
        data = newData;
    }
    return data;
}

/**
 * 获取 数据库某一项 名->值 的映射
 * 例如 getTableIndexValues('basic_info','sex')
 * 返回 Object { "母": "0", "公": "1", "未知": "-1" }
 * 
 * @param table 表名称
 * @param type  字段名
 * @param clone 浅克隆
 * @return 名称到值映射
 * 
 */
function getTableIndexValues(table, type, clone) {
    let data = (indexOfData[table] || {})[type];
    if (clone) {
        let newData = {};
        for (let k in data) newData[k] = data[k];
        data = newData;
    }
    return data;
}

/**
 * 获取某个表内所有字段
 * @param table 表名
 * @return {key:{t:table,v:keyName,n:name}}
 */
function getTableKeys(table) {
    let result = {};
    if (table)
        for (let key in tableKey) {
            if (tableKey[key].t == table) result[key] = tableKey[key];
        }
    return result;
}

let userInfo = { success: null };

/**
 * 登录检查
 * */
async function login_check(cb, flush) {
    return new Promise(r => {
        if (flush || userInfo.success === null)
            $.get({
                url: '/user/check-login',
                beforeSend: req => {
                    req.setRequestHeader("x-access-token", localStorage.getItem("token"));
                },
                success: res => {
                    userInfo = res;
                    cb && cb(!!res.success);
                    r(!!res.success);
                }
            });
        else {
            cb && cb(!!userInfo.success);
            r(!!userInfo.success);
        }
    })
}
/**获取用户信息, 不会返回undefined*/
async function getUserInfo(name) {
    if (!await login_check()) return {};
    return userInfo[name] || {};
}

/**
 * 用户权限检查
 * @param permission 要检查的权限(string/array)
 * @param all 是否要求权限全部通过(仅在permission为array时有用)
 */
async function userHasPermission(permission, all) {
    if (!permission) return null;
    if (permission.constructor.name === 'Array') {
        if (all) {
            for (let index in permission)
                if (!(await userHasPermission(permission[index]))) return false;
            return true;
        } else {
            for (let index in permission)
                if (await userHasPermission(permission[index])) return true;
            return false;
        }
    }
    return await new Promise(r => login_check(s => r(s && !!userInfo.permission[permission])));
}

//百度数据统计
var _hmt = _hmt || [];
$(function() {
    var hm = document.createElement("script");
    hm.src = "https://hm.baidu.com/hm.js?31207b272b6e51a0d4ac38f5863a8974";
    var s = document.getElementsByTagName("script")[0];
    s.parentNode.insertBefore(hm, s);
});

//屏幕检测
(() => {
    const l = window.location,
        pc = "/public/pc.html",
        w = window.innerWidth,
        h = window.innerHeight * 1.2;
    if (window.parent !== window) {
        console.log('viewCheck (none)');
    } else if (l.pathname.endsWith(pc)) {
        console.log('viewCheck (to PE)', w, h, w <= h);
        if (w <= h) l.href = (l.hash || "#/public/cloud-cat.html").substring(1);
    } else {
        console.log('viewCheck (to PC)', w, h, w > h);
        if (w > h) l.href = `${pc}#${l.href.substring(l.href.indexOf(l.pathname))}`;
    }
})();

var onScrollBottom;
//滚动到底部的检测
$(() => {
    $(window).scroll((() => {
        let isBottom = false;
        return function() {
            // $("#nav").css('top', window.scrollY);
            var scrollTop = $(this).scrollTop();
            var scrollHeight = $(document).height();
            var windowHeight = $(this).height();
            if (scrollTop + windowHeight + 100 >= scrollHeight) {
                if (isBottom) return;
                else isBottom = true;
                onScrollBottom && onScrollBottom();
            } else isBottom = false;
        }
    })());
});